from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
import re,random,string,redis
# Create your views here.
class CheckUsername(APIView):
    def get(self,request,username):
    # 1.校验用户名的格式
    # 要求字母开头，中间为字母、数字、下划线，长度5-16
        if not re.findall(r"^[a-zA-Z]\w{4,15}$",username):
            return Response({'code':401,'msg':'用户名格式不正确'})
    # 2.校验用户名是否重复
        if User.objects.filter(username=username).count() > 0:
            return Response({'code':400,'msg':'用户名已存在'})
    # 3.返回校验通过的响应
        return Response({'code':200,'msg':'用户名校验成功'})

class CheckMobile(APIView):
    def get(self,request,mobile):
        # 1.校验手机号
        if not re.findall(r"^1[3-9]\d{9}$",mobile):
            return Response({'code':401,'msg':'手机号格式不正确'})
        # 2.判断手机号是否重复
        if User.objects.filter(mobile=mobile).count() > 0:
            return Response({'code': 400, 'msg': '手机号已存在'})
        # 3.返回校验成功的响应
        return Response({'code': 200, 'msg': '手机号校验成功'})

from captcha.image import ImageCaptcha  #导入图形验证码模块
from django.http import HttpResponse
class ImgCode(APIView):
    def get(self,request,uuid):
        # 1.生成随机的4位验证码 字符串
        # ''.join 字符串拼装
        # random.sample （字符列表，个数）随机取出若干个字符
        # string.digits + string.ascii_letters 数字字符+字母字符
        img_code = ''.join(random.sample(string.digits+string.ascii_letters,4))
        # 2.使用图形验证码模块，将验证码转换图片
        cap = ImageCaptcha()          #生成图形验证码对象
        img = cap.generate(img_code)  #使用对象生成图片
        # 3.将四位字符串保存到redis数据库中
        r = redis.Redis(host='localhost',port=6379,db=5)
        r.set(uuid,img_code,ex=120)  #键：uuid 值:四位随机字符串
        r.close()
        # 4.返回响应图片
        return HttpResponse(img,content_type='image/png')  #返回图片的HttpResponse
    # 校验图形验证码
    def post(self,request,uuid):
        # 1.提取前端传递的图形验证码c1
        c1 = request.data.get('imageCode')
        # 2.提取redis中的图形验证码c2
        r = redis.Redis(host='localhost',port=6379,db=5)
        # 读取数据库中的验证码 键：uuid
        c2 = r.get(uuid)
        # 3.判断c2是否过期  c2需要解码（注意 空数据不能解码decode）
        if c2:
            c2 = c2.decode()  #c2存在，解码
        else:
            return Response({'code':400,'msg':'图形验证码过期'})   #c2过期
        # 4.对比c1和c2是否一致 不区分大小写
        if c1.lower() == c2.lower():
        # 5.返回响应
            return Response({'code':200,'msg':'验证通过'})
        else:
            return Response({'code':400,'msg':'图形验证码错误'})

class Register(APIView):
    def post(self,request):
        # 1.获取前端提交的用户信息
        username = request.data.get('username')
        password = request.data.get('password')
        mobile = request.data.get('mobile')
        agree = request.data.get('agree')
        # 2.校验消息是否完整
        if not all([username,password,mobile,agree]):
            return Response({'code':400,'msg':'字段不完整'})
        # 3.判断是否勾选用户协议
        if not agree:
            return Response({'code':401,'msg':'未勾选用户协议'})
        # 4.创建新用户，返回成功的响应
        User.objects.create(username=username,password=password,mobile=mobile)
        return Response({'code':200,'msg':'注册成功'})

import jwt
from shop_project.settings import SECRET_KEY  #导入密钥
# 用于生成jwt.  user是一个用户模型类对象
def generate_jwt(user):
    payload = {
        'uid':user.id,
        'username':user.username
    }
    # 加密                    载体            密钥              加载方式
    token = jwt.encode(payload=payload, key=SECRET_KEY, algorithm='HS256')
    return token

from django.db.models import Q   #Q查询 用于与或非查询
class Login(APIView):
    def post(self,request):
        # 1.提取前端提交的数据
        username = request.data.get('username')
        password = request.data.get('password')
        # 2.判断用户是否存在
        # if User.objects.filter(username=username).count() == 0:
        #     return Response({'code': 400, 'msg': '用户名不存在'})
        try:
            #补充 多方式登陆
            user = User.objects.get(Q(username=username)|Q(mobile=username))
        except Exception as e:
            print(e)
            return Response({'code': 400, 'msg': '用户名不存在'})
        # 3.判断密码是否正确
        if user.password != password:
            return Response({'code': 401, 'msg': '密码错误'})
        # 补充：生成jwt返回给客户端
        token = generate_jwt(user)
        # 4.登陆成功，返回成功的响应
        return Response({
            'code': 200,
            'msg': '登陆成功',
            'token':token,    #返回jwt字段
            'user':{  #字典 套 字典
                'uid':user.id,
                'userName':user.username,
            }
        })

from  .models import Addr
class UserInfo(APIView):
    #获取用户中心所需的用户信息
    def get(self,request):
        #1.判断用户是否登录
        if request.user_info:
            user_id=request.user_info.get('uid')
            user=User.objects.get(id=user_id)
        else:
            return Response({'code':400,'msg':'用户未登录'})
    #2.获取当前用户的地址信息
        addrs_data=Addr.objects.filter(user_id=user.id)
        addrs_list=[]
        for i in addrs_data:
            addrs_list.append({
                'id':i.id,
                'receiver':i.receiver,
                'receive_mobile':i.receive_mobile,
                'receive_addr':i.receive_addr,
                'is_default':i.is_default,
                'user':i.user_id
            })

        #返回响应
        return Response({
            'code':200,
            'msg':'获取用户信息成功',
            'info':{
                'username':user.username,
                'phone':user.mobile,
                'addrs':addrs_list
            }
        })

class Address(APIView):
    #删除地址
    def delete(self,request):
        if request.user_info:
            user_id = request.user_info.get('uid')
            user = User.objects.get(id=user_id)
        else:
            return Response({'code': 400, 'msg': '用户未登录'})
        #2.接受前端传递过来的地址id，根据id删除
        addr_id=request.data.get('addr_id')
        Addr.objects.get(id=addr_id).delete()
        return Response({'code': 200, 'msg': '删除成功'})
    def put(self,request):
        # 1.判断用户是否登录
        if request.user_info:
            user_id = request.user_info.get('uid')
            user = User.objects.get(id=user_id)
        else:
            return Response({'code': 400, 'msg': '用户未登录'})
        # 2.提取前端提供的数据
        mobile=request.data.get('mobile')
        addrs=request.data.get('addrs')
        #3修改手机号
        user.mobile=mobile
        user.save()#不保存不生效
        #4.修改地址
        for i in addrs:
            Addr.objects.filter(id=i.get('id')).update(
                receiver=i.get('receiver'),
                receive_addr=i.get('receive_addr'),
                receive_mobile=i.get('receive_mobile'),
                is_default=i.get('is_default'),
            )
        return Response({'code': 200, 'msg': '修改成功'})
    #添加收货地址
    def post(self,request):
        #1.判断用户是否登录
        if request.user_info:
            user_id = request.user_info.get('uid')
            user = User.objects.get(id=user_id)
        else:
            return Response({'code': 400, 'msg': '用户未登录'})
        #2.提取前端提供的收货地址信息
        receiver=request.data.get('receiver')
        receive_mobile=request.data.get('receive_mobile')
        receive_addr=request.data.get('receive_addr')
        is_default=request.data.get('is_default')
        #3.如果是默认地址，清除之前的默认地址
        if is_default:
            Addr.objects.filter(is_default=True,user_id=user.id).update(is_default=False)
        Addr.objects.create(
            receiver=receiver,
            receive_addr=receive_addr,
            receive_mobile=receive_mobile,
            is_default=is_default,
            user_id=user.id
        )
        return Response({'code': 200, 'msg': '添加成功'})

class Password(APIView):
    def put(self,request):
        # 1.判断用户是否登录
        if request.user_info:
            user_id = request.user_info.get('uid')
            user = User.objects.get(id=user_id)
        else:
            return Response({'code': 400, 'msg': '用户未登录'})
        #2.获取前端提交的数据
        pwd=request.data.get('pwd')
        new_pwd=request.data.get('new_pwd')
        new_confirm=request.data.get('new_confirm')
        #3.判断原始密码是否与新密码一致
        if pwd!=user.password:
            return Response({'code': 401, 'msg': '原始密码错误'})
        #4.确认密码是否与新密码一致
        if new_pwd!=new_confirm:
            return Response({'code': 402, 'msg': '新密码与旧密码不一致'})
        #修改密码
        user.password=new_pwd
        user.save()
        return Response({'code': 200, 'msg': '修改成功'})

